package com.remenote.remenoteback.service.impl;

import com.remenote.remenoteback.dao.CardRepository;
import com.remenote.remenoteback.dao.DeckRepository;
import com.remenote.remenoteback.entity.doo.CardDo;
import com.remenote.remenoteback.entity.doo.DeckDo;
import com.remenote.remenoteback.entity.req.CardRequest;
import com.remenote.remenoteback.entity.req.DeckRequest;
import com.remenote.remenoteback.entity.resp.ServerResponse;
import com.remenote.remenoteback.entity.vo.DeckVo;
import com.remenote.remenoteback.service.CardService;
import com.remenote.remenoteback.util.ThreadLocalUtil;
import jakarta.transaction.Transactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Slf4j
class CardServiceImpl implements CardService {
    @Autowired
    private CardRepository cardRepository;

    @Autowired
    private DeckRepository deckRepository;

    @Override
    @Transactional
    public ServerResponse<List<DeckVo>> listDecks() {
        List<DeckVo> deckVos = new ArrayList<>();
        List<DeckDo> deckDos = deckRepository.findDeckDoByUsernameAndIsDelete(ThreadLocalUtil.getUserName(), false);
        for (DeckDo deckDo : deckDos) {
            List<CardDo> cardDoList = cardRepository.findCardDoByUsernameAndDeckId(ThreadLocalUtil.getUserName(), deckDo.getId());
            deckVos.add(DeckVo.fromDeckDoAndCardList(deckDo, cardDoList));
        }
        return ServerResponse.buildSuccessResponse(deckVos);
    }

    @Override
    @Transactional
    public ServerResponse<DeckVo> getDeck(Integer deckId) {
        DeckDo deckDo = deckRepository.findDeckDoByIdAndIsDelete(deckId, false);
        List<CardDo> cardDoList = cardRepository.findCardDoByUsernameAndDeckId(ThreadLocalUtil.getUserName(), deckDo.getId());
        DeckVo deckVo = DeckVo.fromDeckDoAndCardList(deckDo, cardDoList);
        return ServerResponse.buildSuccessResponse(deckVo);
    }

    @Override
    @Transactional
    public ServerResponse<List<DeckVo>> search(String keyWord) {
        List<DeckVo> deckVos = new ArrayList<>();
        List<DeckDo> deckDos = deckRepository.findDeckDoByUsernameAndDeckNameContainingAndIsDelete(ThreadLocalUtil.getUserName(), keyWord, false);
        for (DeckDo deckDo : deckDos) {
            List<CardDo> cardDoList = cardRepository.findCardDoByUsernameAndDeckId(ThreadLocalUtil.getUserName(), deckDo.getId());
            deckVos.add(DeckVo.fromDeckDoAndCardList(deckDo, cardDoList));
        }
        return ServerResponse.buildSuccessResponse(deckVos);
    }

    @Override
    @Transactional
    public ServerResponse saveDeck(DeckRequest deckRequest) {
        List<CardRequest> cardRequests = deckRequest.getCardItems();
        for (CardRequest cardRequest : cardRequests) {
            CardDo cardDo = cardRepository.findCardDoById(cardRequest.getId());
            if (Objects.isNull(cardDo)) {
                return ServerResponse.buildErrorResponse("卡片不存在");
            }
            cardDo.setMemoryCount(cardRequest.getMemoryCount());
            cardRepository.save(cardDo);
        }
        return ServerResponse.buildSuccessResponse();
    }

    @Override
    @Transactional
    public ServerResponse createDeck(DeckRequest deckRequest) {
        DeckDo deckDo = new DeckDo()
                .setDeckName(deckRequest.getDeckName())
                .setUsername(ThreadLocalUtil.getUserName());
        deckRepository.save(deckDo);
        List<CardRequest> cardRequests = deckRequest.getCardItems();
        for (CardRequest cardRequest : cardRequests) {
            CardDo cardDo = new CardDo();
            cardDo.setUsername(ThreadLocalUtil.getUserName())
                    .setFront(cardRequest.getFront())
                    .setBack(cardRequest.getBack())
                    .setDeckName(deckRequest.getDeckName())
                    .setMemoryCount(0)
                    .setDeckId(deckDo.getId());
            cardRepository.save(cardDo);
        }

        return ServerResponse.buildSuccessResponse();
    }

    @Override
    @Transactional
    public ServerResponse deleteDeck(Integer deckId) {
        deckRepository.findById(deckId).ifPresent(deckDo -> {
            deckDo.setIsDelete(true);
            deckRepository.save(deckDo);
        });
        return ServerResponse.buildSuccessResponse();
    }
}
